﻿/******************************************************/
// BOLAccount 事業運営クラス  
/******************************************************/

using System;
using System.Data;
using System.Data.SqlClient;
using log4net;
using MAA.Data;
using MAA.Entity;

namespace MAA.Business
{
    /// <summary>
    /// アカウントを管理するために参照の事業運営 
    /// </summary>
    public class BOLAccount
    {
        private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        /// <summary>
        /// ログイン成功またはfalseを定義するには、ユーザー入力のメールアドレスとパスワード、trueまたはfalseとプロセスをチェックします
        /// </summary>
        /// <param name="email"></param>
        /// <param name="password"></param>
        /// <param name="user"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool login(string email, string password, out User user, out string message)
        {
            message = "";
            user = new User();
            DALUser dalUser = new DALUser();

            try
            {
                log.Info("Get detail information of an user based on email");
                // Get detail information of an user based on email
                DataTable tblUser = dalUser.getAccInfo(email);

                // Check getAccInfo: If DataTable has data
                if (tblUser != null && tblUser.Rows.Count > 0)
                {
                    // Push data from DataTable into user
                    for (int i = 0; i < tblUser.Rows.Count; i++)
                    {
                        user.ID = Convert.ToInt64(tblUser.Rows[i]["ID"]);
                        user.Name = Convert.ToString(tblUser.Rows[i]["Name"]).Trim();
                        user.Password = Convert.ToString(tblUser.Rows[i]["Password"]).Trim();
                        user.ProfilePicture = Convert.ToString(tblUser.Rows[i]["ProfilePicture"]).Trim();
                        user.Email = Convert.ToString(tblUser.Rows[i]["Email"]).Trim();
                        user.Phone = Convert.ToString(tblUser.Rows[i]["Phone"]).Trim();
                        user.Address = Convert.ToString(tblUser.Rows[i]["Address"]).Trim();
                        user.ProvinceID = Convert.ToInt16(tblUser.Rows[i]["ProvinceID"]);
                        user.RegisterDate = Convert.ToDateTime(tblUser.Rows[i]["RegisterDate"]);
                        user.ViolationNum = Convert.ToInt16(tblUser.Rows[i]["ViolationNumber"]);
                        user.Status = Convert.ToBoolean(tblUser.Rows[i]["Status"]);
                    }

                    // Check Password: If password != Password of user
                    if (!user.Password.Equals(password))
                    {
                        message = Common.MESSAGE_ERROR_WRONG_PASSWORD;
                        return false;
                    }
                    else
                    {
                        // Check Status: If Status of user = false
                        if (!user.Status)
                        {
                            message = Common.MESSAGE_ERROR_NO_CONFIRM_MAIL;
                            return false;
                        }
                        else
                        {
                            // Check RegisterDate: If RegisterDate of user = null
                            if (user.RegisterDate.Equals(new DateTime()))
                            {
                                message = Common.MESSAGE_ERROR_ACCOUNT_LOCKED;
                                return false;
                            }
                            else
                            {
                                return true;
                            }
                        }
                    }
                }
                else
                {
                    message = Common.MESSAGE_ERROR_ACCOUNT_NOT_EXIST;
                    return false;
                }
            }
            catch (SqlException ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_SQL_FAIL;
                return false;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_CONNECT_DATABASE_FAIL;
                return false;
            }
        }

        /// <summary>
        /// 現在のユーザーの詳細を参照して情報 
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="tblUser"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool viewAccInfo(long userID, out User user, out string message)
        {
            message = "";
            user = new User();
            try
            {
                log.Info("Get detail information of user");
                DALUser dalUser = new DALUser();

                // Lay thong tin chi tiet cua User theo userID tu Database cho vao DataTable User
                DataTable tblUser = dalUser.getAccInfo(userID);

                // If DataTable User co du lieu thi do du lieu vao object User de tra ve
                if (tblUser != null && tblUser.Rows.Count > 0)
                {
                    for (int i = 0; i < tblUser.Rows.Count; i++)
                    {
                        user.Name = Convert.ToString(tblUser.Rows[i]["Name"]).Trim();
                        user.Password = Convert.ToString(tblUser.Rows[i]["Password"]).Trim();
                        user.ProfilePicture = Convert.ToString(tblUser.Rows[i]["ProfilePicture"]).Trim();
                        user.Email = Convert.ToString(tblUser.Rows[i]["Email"]).Trim();
                        user.Phone = Convert.ToString(tblUser.Rows[i]["Phone"]).Trim();
                        user.Address = Convert.ToString(tblUser.Rows[i]["Address"]).Trim();
                        user.ProvinceID = Convert.ToInt16(tblUser.Rows[i]["ProvinceID"]);
                        user.RegisterDate = Convert.ToDateTime(tblUser.Rows[i]["RegisterDate"]);
                        user.ViolationNum = Convert.ToInt16(tblUser.Rows[i]["ViolationNumber"]);
                        user.Status = Convert.ToBoolean(tblUser.Rows[i]["Status"]);
                    }
                }

                return true;
            }
            catch (SqlException ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_SQL_FAIL;
                return false;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_CONNECT_DATABASE_FAIL;
                return false;
            }
        }

        /// <summary>
        /// 販売者のビュー情報は、ポストに対応 
        /// </summary>
        /// <param name="postID"></param>
        /// <param name="userID"></param>
        /// <param name="tblSeller"></param>
        /// <param name="reported"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool viewSellerInfo(long userID, long sellerID, out DataTable tblSeller, out bool reported, out string message)
        {
            message = "";
            tblSeller = null;
            reported = false;

            DALUser dalUser = new DALUser();
            try
            {
                log.Info("Get detail information of seller correspond to the post");

                // Get detail information of seller correspond to the post
                tblSeller = dalUser.getAccInfo(sellerID);

                if (tblSeller.Rows.Count > 0)
                {
                    // Check xem da report violation chua
                    DataTable tblBreach = dalUser.getBreachReport(userID, sellerID);
                    if (tblBreach.Rows.Count > 0)
                    {
                        reported = true;
                    }
                    else
                    {
                        reported = false;
                    }
                }

                return true;
            }
            catch (SqlException ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_SQL_FAIL;
                return false;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_CONNECT_DATABASE_FAIL;
                return false;
            }
        }

        /// <summary>
        /// 新しいユーザーアカウントを作成します
        /// </summary>
        /// <param name="user"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool register(User user, out string message)
        {
            message = "";
            DALUser dalUser = new DALUser();

            try
            {
                log.Info("Register");

                // Check email has been already used to register: If Check is true
                DataTable tblUser = dalUser.getAccInfo(user.Email);
                if (tblUser != null && tblUser.Rows.Count > 0)
                {
                    message = Common.MESSAGE_ERROR_EMAIL_EXIST;
                    return false;
                }
                else
                {
                    // Perform register
                    user.RegisterDate = DateTime.UtcNow.Date;
                    user.ProfilePicture = Common.URL_PROFILE_IMAGE + Common.DEFAULT_PROFILE_IMAGE_NAME;
                    dalUser.insertAcc(user);

                    // Send confirm email
                    string bodyMail = string.Format(Common.SEND_EMAIL_CONFIRM_BODY, user.Email);
                    bool sendEmail = BOLCommon.SendMailMulti(Common.SEND_EMAIL_SERVER,
                                                    Common.SEND_EMAIL_USER, Common.SEND_EMAIL_PASSWORD,
                                                    Common.SEND_EMAIL_PORT, Common.SEND_EMAIL_DISPLAY_NAME,
                                                    Common.SEND_EMAIL_FROM,
                                                    user.Email, Common.SEND_EMAIL_CC, Common.SEND_EMAIL_BCC,
                                                    Common.SEND_EMAIL_SUBJECT + " Confirm register",
                                                    bodyMail, true, true);
                    if (sendEmail)
                    {
                        message = Common.MESSAGE_SUCCESS_REGISTER;
                        return true;
                    }
                    else
                    {
                        message = Common.MESSAGE_ERROR_SEND_EMAIL_FAIL;
                        return false;
                    }
                }

            }
            catch (SqlException ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_SQL_FAIL;
                return false;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_CONNECT_DATABASE_FAIL;
                return false;
            }
        }

        /// <summary>
        /// アクティブ登録済みのアカウント 
        /// </summary>
        /// <param name="email"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool activeAccount(string email, out string message)
        {
            message = "";
            DALUser dalUser = new DALUser();

            try
            {
                log.Info("Perform active account");

                /// アクティブなアカウントを実行
                dalUser.activeAcc(email);
                message = Common.MESSAGE_SUCCESS_CONFIRM_MAIL;

                return true;
            }
            catch (SqlException ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_SQL_FAIL;
                return false;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_CONNECT_DATABASE_FAIL;
                return false;
            }
        }

        /// <summary>
        /// 現在のユーザーアカウントの情報を編集 
        /// </summary>
        /// <param name="accInfo"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool editAccount(User user, out string message)
        {
            message = "";
            try
            {
                log.Info("Update information of user");
                DALUser dalUser = new DALUser();
                // Update thong tin nguoi dung trong database
                dalUser.updateAcc(user);
                return true;
            }
            catch (SqlException ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_SQL_FAIL;
                return false;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_CONNECT_DATABASE_FAIL;
                return false;
            }
        }

        /// <summary>
        /// 現在のユーザーアカウントの編集用パスワード 
        /// </summary>
        /// <param name="oldPass"></param>
        /// <param name="newPass"></param>
        /// <param name="newPassCf"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool changePassword(long userID, string oldPass, string newPass, out string message)
        {
            message = "";
            string oldPassDB = "";
            DALUser dalUser = new DALUser();
            try
            {
                log.Info("Change Password");

                // Lay old password trong database base on userID
                DataTable tblOldPass = dalUser.getPassWord(userID);
                // Neu datatable du lieu thi lay old password tu trong datatable
                if (tblOldPass != null && tblOldPass.Rows.Count > 0)
                {
                    for (int i = 0; i < tblOldPass.Rows.Count; i++)
                    {
                        oldPassDB = Convert.ToString(tblOldPass.Rows[i]["Password"]).Trim();
                    }
                }
            }
            catch (SqlException ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_SQL_FAIL;
                return false;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_CONNECT_DATABASE_FAIL;
                return false;
            }
            // So sanh old password user nhap voi old password vua lay tu database, neu khac nhau -> change password loi
            if (!oldPass.Equals(oldPassDB))
            {
                message = Common.MESSAGE_ERROR_WRONG_PASSWORD;
                return false;
            }
            else
            {
                try
                {
                    log.Info("Edit password");
                    //Sua password trong database
                    dalUser.updateAcc(userID, newPass);
                    return true;
                }
                catch (SqlException ex)
                {
                    log.Error(ex.Message);
                    log.Error(ex.StackTrace);
                    log.Error(ex.TargetSite);
                    message = Common.MESSAGE_ERROR_SQL_FAIL;
                    return false;
                }
                catch (Exception ex)
                {
                    log.Error(ex.Message);
                    log.Error(ex.StackTrace);
                    log.Error(ex.TargetSite);
                    message = Common.MESSAGE_ERROR_CONNECT_DATABASE_FAIL;
                    return false;
                }
            }

        }

        /// <summary>
        /// 現在のポストの売り手が違反されているレポート
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="violatorID"></param>
        /// <param name="reason"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool reportBreach(long userID, long violatorID, string reason, out string message)
        {
            message = "";

            DALUser dalUser = new DALUser();

            try
            {
                log.Info("Report Breach");
                // Insert breach report
                dalUser.insertBreach(userID, violatorID, reason);

                // Get violation number of seller
                DataTable tblSeller = dalUser.getViolationNumber(violatorID);
                short violationNum = 0;
                if (tblSeller.Rows.Count > 0)
                {
                    for (int i = 0; i < tblSeller.Rows.Count; ++i)
                    {
                        violationNum = Convert.ToInt16(tblSeller.Rows[i]["ViolationNumber"]);
                    }
                }

                // If violation number of seller = 20 (before update violation number of that seller)
                if (violationNum == 20)
                {
                    // Update violation number & block account of seller
                    dalUser.updateAcc(violatorID, true);

                    // Send email to Seller thong bao tai khoan da bi khoa
                }
                else
                {
                    // Only update violation number of seller
                    dalUser.updateAcc(violatorID, false);
                }
                return true;
            }
            catch (SqlException ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_SQL_FAIL;
                return false;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                log.Error(ex.TargetSite);
                message = Common.MESSAGE_ERROR_CONNECT_DATABASE_FAIL;
                return false;
            }
        }
    }
}